package com.donger.common.log.aop;

import com.donger.common.client.upms.entity.RpcCommonLog;
import com.donger.common.client.upms.service.RpcCommonService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalTime;

/**
 * 日志AOP
 * com.donger.common.log.aop.LogAop
 *
 * @author aeizzz
 * @date 2019-01-10 21:03
 */
@Slf4j
@Aspect
@Component
@Configuration
@AllArgsConstructor
public class LogAop {

    private final RpcCommonService rpcCommonService;

    @Pointcut(value = "@annotation(com.donger.common.log.annotation.AutoLog)")
    public void cutService() {
    }

    @Around("cutService()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {

        long startTime = System.currentTimeMillis();
        //先执行业务
        Object result = point.proceed();
        long endTime = System.currentTimeMillis();
        try {
            handle(point, endTime - startTime, null);
        } catch (Exception e) {
            log.error("日志记录出错!", e);
        }
        return result;
    }

    @AfterThrowing(pointcut = "cutService()", throwing = "e")
    public void doAfterThrowing(JoinPoint point, Throwable e) {
        try {
            handle(point, null, e);
        } catch (Exception ex) {
            log.error("日志记录出错!", ex);
        }
    }

    @Async
    void handle(JoinPoint point, Long methodProcessTime, Throwable e) throws Exception {
        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
        //获取拦截方法的参数
        Object[] params = point.getArgs();
        //获取操作名称

        RpcCommonLog log = new RpcCommonLog();
        log.setModule(methodName);
        log.setBusinessData("");
        log.setData(LocalDate.now());
        log.setTime(LocalTime.now());
        // 保存业务数据
        rpcCommonService.saveCommonLog(log);
    }

}
